/*
 * Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *         http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

/**
 * @file global_functions.h
 * @brief Python 全局函数的 C++ 实现
 */

#ifndef MC_BUILTINS_GLOBAL_FUNCTIONS_H
#define MC_BUILTINS_GLOBAL_FUNCTIONS_H

#include <algorithm>
#include <cstddef>
#include <functional>
#include <iterator>
#include <numeric>
#include <type_traits>
#include <unordered_set>
#include <vector>

#include "mcpy/builtins/any_value.h"
#include "mcpy/builtins/cast.h"
#include "mcpy/exception.h"

// 前向声明 mcpy::set 和 variant_set（避免循环依赖）
namespace mcpy {
template <typename T, typename Hash, typename KeyEqual, typename Allocator>
class set;
using variant_set = set<mc::variant, std::hash<mc::variant>, std::equal_to<mc::variant>, std::allocator<mc::variant>>;
} // namespace mcpy

namespace mcpy {

// ============================================================================
// 类型特征：检测容器是否是键值对容器
// ============================================================================

namespace detail {

// ============================================================================
// storage_type: 自动选择存储策略（值 vs 引用）
// ============================================================================

/**
 * @brief 根据参数类型自动选择存储策略
 *
 * - 左值引用（const T& 或 T&）→ 存储 const T&（零拷贝）
 * - 右值引用（T&&）→ 存储 T（拥有数据）
 *
 * 这样可以：
 * 1. 避免拷贝左值容器
 * 2. 正确持有临时对象（右值）
 * 3. 简化函数重载（只需一个函数）
 */
template <typename T>
struct storage_type {
    using raw_type = std::remove_reference_t<T>;

    using type = std::conditional_t<
        std::is_lvalue_reference_v<T>, // 如果是左值引用
        std::add_lvalue_reference_t<   // 存储 const T&
            std::add_const_t<raw_type>>,
        raw_type // 否则存储 T（移动语义）
        >;
};

template <typename T>
using storage_type_t = typename storage_type<T>::type;

// 检测类型是否支持 std::size()
template <typename T, typename = void>
struct has_std_size : std::false_type {};

template <typename T>
struct has_std_size<T, std::void_t<decltype(std::size(std::declval<const T&>()))>>
    : std::true_type {};

// 检测类型是否有 key 成员
template <typename Container, typename = void>
struct has_key_member : std::false_type {};

template <typename Container>
struct has_key_member<Container, std::void_t<typename Container::key_type>>
    : std::true_type {};

// 检测容器的 value_type 是否是键值对类型
template <typename Container>
struct is_key_value_container {
    using value_type            = typename Container::value_type;
    static constexpr bool value = has_key_member<Container>::value && !std::is_void_v<value_type>;
};

// 获取键值对类型的 key 类型
template <typename T, typename = void>
struct key_type_of {
    using type = T; // 默认：非键值对类型，返回自身
};

template <typename T>
struct key_type_of<T, std::enable_if_t<has_key_member<T>::value>> {
    using type = std::remove_cv_t<std::remove_reference_t<decltype(std::declval<T>().key)>>;
};

} // namespace detail

// ============================================================================
// zip 函数 - 并行迭代多个容器
// ============================================================================

namespace detail {

/**
 * @brief zip 迭代器视图（泛型版本）
 *
 * 提供 Python zip(container1, container2) 的功能
 * 支持所有容器：list, set, vector, unordered_set 等
 *
 * 模板参数：
 * - Container1/Container2: 容器类型（从 Holder 中推导）
 * - Holder1/Holder2: 存储策略（引用类型 = 零拷贝，值类型 = 拥有数据）
 */
template <typename Container1, typename Container2, typename Holder1, typename Holder2>
class zip_view {
public:
    using container_type1 = std::remove_reference_t<Container1>;
    using container_type2 = std::remove_reference_t<Container2>;
    using base_iterator1  = typename container_type1::const_iterator;
    using base_iterator2  = typename container_type2::const_iterator;
    using value_type1     = typename container_type1::value_type;
    using value_type2     = typename container_type2::value_type;
    using value_type      = std::tuple<value_type1, value_type2>;

    // 迭代器
    class iterator {
    public:
        using iterator_category = std::forward_iterator_tag;
        using value_type        = std::tuple<value_type1, value_type2>;
        using difference_type   = std::ptrdiff_t;
        using pointer           = value_type*;
        using reference         = value_type; // 返回值类型（不是真正的引用）

        iterator(base_iterator1 it1, base_iterator2 it2, base_iterator1 end1, base_iterator2 end2)
            : m_it1(it1), m_it2(it2), m_end1(end1), m_end2(end2) {
        }

        reference operator*() const {
            return std::make_tuple(*m_it1, *m_it2);
        }

        iterator& operator++() {
            if (m_it1 != m_end1) {
                ++m_it1;
            }
            if (m_it2 != m_end2) {
                ++m_it2;
            }
            return *this;
        }

        iterator operator++(int) {
            iterator tmp = *this;
            ++(*this);
            return tmp;
        }

        bool operator==(const iterator& other) const {
            // 任一迭代器到达末尾就相等（支持不同长度的容器）
            return m_it1 == m_end1 || m_it2 == m_end2 ||
                   (m_it1 == other.m_it1 && m_it2 == other.m_it2);
        }
        bool operator!=(const iterator& other) const {
            return !(*this == other);
        }

    private:
        base_iterator1 m_it1;
        base_iterator2 m_it2;
        base_iterator1 m_end1; // 用于判断是否到达末尾
        base_iterator2 m_end2;
    };

    zip_view(Holder1 c1, Holder2 c2)
        : m_holder1(std::forward<Holder1>(c1)), m_holder2(std::forward<Holder2>(c2)) {
    }

    iterator begin() const {
        return iterator(get_container1().begin(), get_container2().begin(),
                        get_container1().end(), get_container2().end());
    }

    iterator end() const {
        // zip 以较短的容器为准
        auto size1 = get_container1().size();
        auto size2 = get_container2().size();

        if (size1 <= size2) {
            return iterator(get_container1().end(), get_container2().begin(),
                            get_container1().end(), get_container2().end());
        } else {
            return iterator(get_container1().begin(), get_container2().end(),
                            get_container1().end(), get_container2().end());
        }
    }

    std::size_t size() const {
        return std::min(get_container1().size(), get_container2().size());
    }

private:
    Holder1 m_holder1;
    Holder2 m_holder2;

    const container_type1& get_container1() const {
        if constexpr (std::is_reference_v<Holder1>) {
            return m_holder1;
        } else {
            return m_holder1;
        }
    }

    const container_type2& get_container2() const {
        if constexpr (std::is_reference_v<Holder2>) {
            return m_holder2;
        } else {
            return m_holder2;
        }
    }
};

// ============================================================================
// enumerate_result_builder: SFINAE 辅助类型，根据容器类型构造不同的结果
// ============================================================================

// 前向声明
template <typename Container, typename Iterator, typename = void>
struct enumerate_result_builder;

// 特化 1：值容器（list, set, vector 等）
// 检测条件：迭代器解引用后的类型**没有** key 成员
template <typename Container, typename Iterator>
struct enumerate_result_builder<Container, Iterator,
                                std::enable_if_t<!has_key_member<decltype(*std::declval<Iterator>())>::value>> {
    using element_type = std::remove_reference_t<decltype(*std::declval<Iterator>())>;
    using result_type  = std::tuple<int, element_type>;

    static result_type make(int index, Iterator it) {
        // 值容器：直接返回 (索引, 元素)
        return result_type{index, *it};
    }
};

// 特化 2：键值对容器（dict, map, unordered_map 等）
// 检测条件：迭代器解引用后的类型**有** key 成员
template <typename Container, typename Iterator>
struct enumerate_result_builder<Container, Iterator,
                                std::enable_if_t<has_key_member<decltype(*std::declval<Iterator>())>::value>> {
    using entry_type   = std::remove_reference_t<decltype(*std::declval<Iterator>())>;
    using element_type = typename key_type_of<entry_type>::type;
    using result_type  = std::tuple<int, element_type>;

    static result_type make(int index, Iterator it) {
        // 键值对容器：返回 (索引, 键)
        return result_type{index, (*it).key};
    }
};

/**
 * @brief enumerate 迭代器视图（通用版本）
 *
 * 提供 Python enumerate(iterable, start=0) 的功能
 * 支持所有容器：list, set, dict, vector, unordered_set 等
 *
 * 对于键值对容器（dict, map），自动迭代键而不是 entry/pair
 *
 * 模板参数：
 * - Container: 容器类型（从 Holder 中推导）
 * - Holder: 存储策略（引用类型 = 零拷贝，值类型 = 拥有数据）
 */
template <typename Container, typename Holder>
class enumerate_view {
public:
    using container_type = std::remove_reference_t<Container>;
    using base_iterator  = typename container_type::const_iterator;

    // 使用 SFINAE 辅助类型自动推导结果类型
    using builder_type = detail::enumerate_result_builder<container_type, base_iterator>;
    using result_type  = typename builder_type::result_type;

    // 迭代器
    class iterator {
    public:
        using iterator_category = std::forward_iterator_tag;
        using value_type        = result_type;
        using difference_type   = std::ptrdiff_t;
        using pointer           = result_type*;
        using reference         = result_type; // 返回值类型（不是真正的引用）
        using base_iterator     = typename container_type::const_iterator;

        iterator(base_iterator it, int index) : m_it(it), m_index(index) {
        }

        reference operator*() const {
            return builder_type::make(m_index, m_it);
        }
        iterator& operator++() {
            ++m_it;
            ++m_index;
            return *this;
        }

        iterator operator++(int) {
            iterator tmp = *this;
            ++(*this);
            return tmp;
        }

        bool operator==(const iterator& other) const {
            return m_it == other.m_it;
        }
        bool operator!=(const iterator& other) const {
            return m_it != other.m_it;
        }

    private:
        base_iterator m_it;
        int           m_index;
    };

    explicit enumerate_view(Holder container, int start = 0)
        : m_holder(std::forward<Holder>(container)), m_start(start) {
    }

    iterator begin() const {
        return iterator(get_container().begin(), m_start);
    }

    iterator end() const {
        return iterator(get_container().end(), m_start + static_cast<int>(get_container().size()));
    }

    std::size_t size() const {
        return get_container().size();
    }

private:
    Holder m_holder;
    int    m_start;

    const container_type& get_container() const {
        if constexpr (std::is_reference_v<Holder>) {
            return m_holder;
        } else {
            return m_holder;
        }
    }
};

} // namespace detail

// ============================================================================
// enumerate 函数 - 为可迭代对象添加索引
// ============================================================================

/**
 * @brief 创建 enumerate 视图的辅助函数（统一版本）
 *
 * Python: enumerate(container, start=0)
 * C++:    mcpy::enumerate(container, start)
 *
 * 使用完美转发 + 存储策略自动推导：
 * - 左值容器 → 存储 const Container&（零拷贝）
 * - 右值容器 → 存储 Container（移动语义，拥有数据）
 *
 * 示例：
 *   mc::array<int> v = {1, 2, 3};
 *   enumerate(v)        // 存储 const mc::array<int>&
 *   enumerate({1,2,3})  // 存储 mc::array<int>（临时对象）
 */
template <typename Container>
inline auto enumerate(Container&& container, int start = 0) {
    using ContainerType = std::remove_cv_t<std::remove_reference_t<Container>>;
    using StorageType   = detail::storage_type_t<Container&&>;
    return detail::enumerate_view<ContainerType, StorageType>(
        std::forward<Container>(container), start);
}

// ============================================================================
// zip 函数 - 并行迭代多个容器
// ============================================================================

/**
 * @brief 创建 zip 视图的辅助函数（统一版本，支持任意左值/右值组合）
 *
 * Python: zip(container1, container2)
 * C++:    mcpy::zip_view(container1, container2)
 *
 * 使用完美转发 + 存储策略自动推导：
 * - 左值容器 → 存储 const Container&（零拷贝）
 * - 右值容器 → 存储 Container（移动语义，拥有数据）
 *
 * 示例：
 *   mc::array<int> v1 = {1, 2, 3};
 *   mcpy::set<int> s2 = {4, 5, 6};
 *   zip_view(v1, s2)       // 两个左值：const&
 *   zip_view(v1, {4,5,6})  // v1: const&, {4,5,6}: 移动
 *
 * 支持任意容器类型：vector, list, set, unordered_set 等
 */
template <typename T1, typename T2>
inline auto zip_view(T1&& c1, T2&& c2) {
    using Container1   = std::remove_cv_t<std::remove_reference_t<T1>>;
    using Container2   = std::remove_cv_t<std::remove_reference_t<T2>>;
    using StorageType1 = detail::storage_type_t<T1&&>;
    using StorageType2 = detail::storage_type_t<T2&&>;

    return detail::zip_view<Container1, Container2, StorageType1, StorageType2>(
        std::forward<T1>(c1), std::forward<T2>(c2));
}

// ============================================================================
// 聚合函数 - min, max, any, all, sum
// ============================================================================

/**
 * @brief 返回可迭代对象中的最小元素
 *
 * @tparam T 返回类型
 * @tparam Range 容器类型
 * @param range 可迭代容器
 * @return T 最小值
 * @throw mcpy::value_error 如果容器为空
 */
template <typename T, typename Range>
inline T iterable_min(Range&& range) {
    auto it  = std::begin(range);
    auto end = std::end(range);

    if (it == end) {
        MC_THROW(mcpy::value_error, "min() arg is an empty sequence");
    }

    auto min_it = std::min_element(it, end);

    using value_type = std::decay_t<decltype(*min_it)>;
    if constexpr (mc::is_variant_v<value_type> && !mc::is_variant_v<T>) {
        return mcpy::cast<T>(*min_it);
    } else {
        return *min_it;
    }
}

/**
 * @brief 返回可迭代对象中的最大元素
 *
 * @tparam T 返回类型
 * @tparam Range 容器类型
 * @param range 可迭代容器
 * @return T 最大值
 * @throw mcpy::value_error 如果容器为空
 */
template <typename T, typename Range>
inline T iterable_max(Range&& range) {
    auto it  = std::begin(range);
    auto end = std::end(range);

    if (it == end) {
        MC_THROW(mcpy::value_error, "max() arg is an empty sequence");
    }

    auto max_it = std::max_element(it, end);

    using value_type = std::decay_t<decltype(*max_it)>;
    if constexpr (mc::is_variant_v<value_type> && !mc::is_variant_v<T>) {
        return cast<T>(*max_it);
    } else {
        return *max_it;
    }
}

/**
 * @brief 检查可迭代对象中是否有任意元素为真
 *
 * Python: any(iterable)
 * C++:    mcpy::iterable_any(iterable)
 *
 * @param range 可迭代容器
 * @return 如果任一元素为真则返回 true
 */
template <typename Range>
inline bool iterable_any(Range&& range) {
    return std::any_of(std::begin(range), std::end(range), [](auto&& item) {
        return static_cast<bool>(item);
    });
}

/**
 * @brief 检查可迭代对象中是否所有元素都为真
 *
 * Python: all(iterable)
 * C++:    mcpy::iterable_all(iterable)
 *
 * @param range 可迭代容器
 * @return 如果所有元素都为真则返回 true（空容器返回 true）
 */
template <typename Range>
inline bool iterable_all(Range&& range) {
    return std::all_of(std::begin(range), std::end(range), [](auto&& item) {
        return static_cast<bool>(item);
    });
}

/**
 * @brief 对可迭代对象进行累加求和（无起始值，默认为 0）
 *
 * @tparam Range 容器类型
 * @param range 可迭代容器
 * @return 所有元素的和（空序列返回 0）
 */
template <typename Range>
inline auto reduce_sum(Range&& range)
    -> decltype(0 + *std::begin(range)) {
    using result_type = decltype(0 + *std::begin(range));

    auto it  = std::begin(range);
    auto end = std::end(range);

    // 空序列返回 0（与 Python 行为一致）
    if (it == end) {
        return result_type(0);
    }

    // 使用第一个元素作为初始值
    result_type result = *it;
    ++it;

    // 累加剩余元素
    for (; it != end; ++it) {
        result = result + *it;
    }

    return result;
}

/**
 * @brief 对可迭代对象进行累加求和（带起始值）
 *
 * @tparam Range 容器类型
 * @tparam T 起始值类型
 * @param range 可迭代容器
 * @param init 起始值
 * @return 所有元素的和加上起始值
 */
template <typename Range, typename T>
inline T reduce_sum(Range&& range, T&& init) {
    using value_type = std::decay_t<decltype(*std::begin(range))>;

    T result = std::forward<T>(init);

    // 如果容器元素是 mc::variant 但累加类型 T 不是，需要转换
    if constexpr (mc::is_variant_v<value_type> && !mc::is_variant_v<std::decay_t<T>>) {
        for (const auto& item : range) {
            result = result + cast<std::decay_t<T>>(item);
        }
    } else {
        for (const auto& item : range) {
            result = result + item;
        }
    }

    return result;
}

// ============================================================================
// sorted 函数 - 返回排序后的新容器
// ============================================================================

/**
 * @brief 返回排序后的新容器
 *
 * @tparam T 元素类型（Python 侧推断得出）
 * @tparam Range 容器类型
 * @param range 可迭代容器
 * @param reverse 是否反向排序（默认 false）
 * @return 排序后的新容器 mc::array<T>
 */
template <typename T, typename Range>
inline mc::array<T> iterable_sorted(Range&& range, bool reverse = false) {
    using value_type = std::decay_t<decltype(*std::begin(range))>;

    mc::array<T> result;

    // 如果容器元素是 mc::variant 但目标类型 T 不是，需要转换
    if constexpr (mc::is_variant_v<value_type> && !mc::is_variant_v<T>) {
        for (const auto& item : range) {
            result.push_back(cast<T>(item));
        }
    } else {
        for (const auto& item : range) {
            result.push_back(item);
        }
    }

    if (reverse) {
        std::sort(result.begin(), result.end(), std::greater<T>());
    } else {
        std::sort(result.begin(), result.end());
    }

    return result;
}

// ============================================================================
// reversed 函数 - 反向迭代视图
// ============================================================================

namespace detail {

/**
 * @brief reversed 迭代器视图
 *
 * 提供 Python reversed(sequence) 的功能
 * 使用反向迭代器实现，支持所有具有双向迭代器的容器
 *
 * 模板参数：
 * - Container: 容器类型
 * - Holder: 存储策略（引用类型 = 零拷贝，值类型 = 拥有数据）
 */
template <typename Container, typename Holder>
class reversed_view {
public:
    using container_type   = std::remove_reference_t<Container>;
    using value_type       = typename container_type::value_type;
    using reverse_iterator = typename container_type::const_reverse_iterator;

    explicit reversed_view(Holder container)
        : m_holder(std::forward<Holder>(container)) {
    }

    reverse_iterator begin() const {
        return get_container().rbegin();
    }

    reverse_iterator end() const {
        return get_container().rend();
    }

    std::size_t size() const {
        return get_container().size();
    }

private:
    Holder m_holder;

    const container_type& get_container() const {
        if constexpr (std::is_reference_v<Holder>) {
            return m_holder;
        } else {
            return m_holder;
        }
    }
};

} // namespace detail

/**
 * @brief 创建 reversed 视图的辅助函数
 *
 * Python: reversed(sequence)
 * C++:    mcpy::iterable_reversed(sequence)
 *
 * 使用完美转发 + 存储策略自动推导：
 * - 左值容器 → 存储 const Container&（零拷贝）
 * - 右值容器 → 存储 Container（移动语义，拥有数据）
 *
 * 示例：
 *   mc::array<int> v = {1, 2, 3};
 *   iterable_reversed(v)        // 存储 const mc::array<int>&
 *   iterable_reversed({1,2,3})  // 存储 mc::array<int>（临时对象）
 */
template <typename Container>
inline auto iterable_reversed(Container&& container) {
    using ContainerType = std::remove_cv_t<std::remove_reference_t<Container>>;
    using StorageType   = detail::storage_type_t<Container&&>;
    return detail::reversed_view<ContainerType, StorageType>(std::forward<Container>(container));
}

// ============================================================================
// count 函数 - 返回容器元素数量
// ============================================================================

/**
 * @brief 返回容器的元素数量
 *
 * Python: len(iterable) 的内部实现
 * C++:    mcpy::iterable_count(iterable)
 *
 * @param range 可迭代容器
 * @return 元素数量
 */
template <typename Range>
inline std::size_t iterable_count(Range&& range) {
    using R = std::decay_t<Range>;
    if constexpr (detail::has_std_size<R>::value) {
        return static_cast<std::size_t>(std::size(range));
    } else {
        return static_cast<std::size_t>(std::distance(std::begin(range), std::end(range)));
    }
}

// ============================================================================
// range() 函数 - 生成整数序列容器
// ============================================================================

namespace detail {

/**
 * @brief range 容器的迭代器
 *
 * 实现前向迭代器，用于遍历整数序列
 */
class range_iterator {
public:
    using value_type        = int;
    using difference_type   = std::ptrdiff_t;
    using pointer           = const int*;
    using reference         = const int&;
    using iterator_category = std::forward_iterator_tag;

private:
    int m_value;
    int m_step;

public:
    range_iterator() : m_value(0), m_step(1) {
    }

    range_iterator(int value, int step) : m_value(value), m_step(step) {
    }

    // 前向迭代器操作
    reference operator*() const {
        return m_value;
    }

    range_iterator& operator++() {
        m_value += m_step;
        return *this;
    }

    range_iterator operator++(int) {
        range_iterator tmp = *this;
        ++(*this);
        return tmp;
    }

    bool operator==(const range_iterator& other) const {
        // 注意：只比较值，不比较步长
        // 结束迭代器通过值比较来判断
        return m_value == other.m_value;
    }

    bool operator!=(const range_iterator& other) const {
        return !(*this == other);
    }
};

/**
 * @brief range 容器类
 *
 * 轻量级的整数序列容器，支持 range-based for 循环和标准迭代器接口
 * 类似于 Python 的 range()，但不预先分配内存
 */
class MC_API range_container {
private:
    int m_start;
    int m_stop;
    int m_step;

public:
    using value_type     = int;
    using iterator       = detail::range_iterator;
    using const_iterator = detail::range_iterator;
    using size_type      = std::size_t;

    /**
     * @brief 构造 range(stop) 容器
     *
     * 生成 [0, 1, 2, ..., stop-1]
     */
    explicit range_container(int stop) : m_start(0), m_stop(stop), m_step(1) {
    }

    /**
     * @brief 构造 range(start, stop) 容器
     *
     * 生成 [start, start+1, ..., stop-1]
     */
    range_container(int start, int stop) : m_start(start), m_stop(stop), m_step(1) {
    }

    /**
     * @brief 构造 range(start, stop, step) 容器（暂不支持，但保留接口）
     */
    range_container(int start, int stop, int step) : m_start(start), m_stop(stop), m_step(step) {
    }

    /**
     * @brief 返回起始迭代器
     */
    const_iterator begin() const {
        return const_iterator(m_start, m_step);
    }

    /**
     * @brief 返回结束迭代器
     */
    const_iterator end() const {
        return const_iterator(m_stop, m_step);
    }

    /**
     * @brief 返回容器大小
     *
     * 计算序列中的元素数量
     * 对于 range(stop): 返回 max(0, stop)
     * 对于 range(start, stop): 返回 max(0, stop - start)
     */
    size_type size() const;
    /**
     * @brief 检查容器是否为空
     */
    bool empty() const {
        return size() == 0;
    }
};

} // namespace detail

/**
 * @brief Python range(stop) 函数的实现
 *
 * Python: range(stop) -> range_container
 * C++:    mcpy::range(stop) -> detail::range_container
 *
 * 生成 [0, 1, 2, ..., stop-1] 的整数序列容器
 *
 * @param stop 结束值（不包含）
 * @return detail::range_container 整数序列容器
 */
inline detail::range_container range(int stop) {
    return detail::range_container(stop);
}

/**
 * @brief Python range(start, stop) 函数的实现
 *
 * Python: range(start, stop) -> range_container
 * C++:    mcpy::range(start, stop) -> detail::range_container
 *
 * 生成 [start, start+1, ..., stop-1] 的整数序列容器
 *
 * @param start 起始值（包含）
 * @param stop 结束值（不包含）
 * @return detail::range_container 整数序列容器
 */
inline detail::range_container range(int start, int stop) {
    return detail::range_container(start, stop);
}

// ============================================================================
// iter() 和 next() 函数 - 迭代器协议支持
// ============================================================================

namespace detail {

/**
 * @brief 通用的迭代器包装类
 *
 * 实现 Python 的迭代器协议，支持 StopIteration 异常
 *
 * 通过模板参数 Holder 控制存储方式：
 * - 引用类型 → 零拷贝
 * - 值类型 → 拥有数据（支持临时容器）
 *
 * @tparam Container 容器类型（从 Holder 中推导）
 * @tparam Holder 存储策略（const Container& 或 Container）
 */
template <typename Container, typename Holder>
class iterator_wrapper {
public:
    using container_type = std::remove_reference_t<Container>;
    using base_iterator  = typename container_type::const_iterator;
    using value_type     = std::remove_reference_t<decltype(*std::declval<base_iterator>())>;

private:
    const container_type*                            m_container_ptr; // 统一用指针
    any_value_for_t<std::remove_reference_t<Holder>> m_storage;       // 存储值类型
    mutable std::optional<base_iterator>             m_it;

public:
    iterator_wrapper() : m_container_ptr(nullptr) {
    }

    explicit iterator_wrapper(Holder container) : m_container_ptr(nullptr) {
        if constexpr (std::is_reference_v<Holder>) {
            // 左值引用：直接存储指针
            m_container_ptr = &container;
        } else {
            // 右值：存储到 any_value，然后指向它
            m_storage.template emplace<std::remove_reference_t<Holder>>(std::move(container));
            m_container_ptr = &m_storage.template get<std::remove_reference_t<Holder>>();
        }
    }

    // 拷贝构造函数
    iterator_wrapper(const iterator_wrapper& other) = default;

    // 移动构造函数
    iterator_wrapper(iterator_wrapper&& other) noexcept = default;

    // 赋值操作符
    iterator_wrapper& operator=(iterator_wrapper&& other) noexcept = default;
    iterator_wrapper& operator=(const iterator_wrapper& other)     = default;

    // 模板化赋值操作符（允许不同的 Holder 类型）
    template <typename OtherHolder>
    iterator_wrapper& operator=(iterator_wrapper<Container, OtherHolder>&& other) {
        m_container_ptr = other.m_container_ptr;
        m_storage       = std::move(other.m_storage);
        m_it            = other.m_it;
        // 如果 other 拥有值，需要更新指针
        if (!m_storage.empty()) {
            m_container_ptr = &m_storage.template get<std::remove_reference_t<OtherHolder>>();
        }
        return *this;
    }

    template <typename OtherHolder>
    iterator_wrapper& operator=(const iterator_wrapper<Container, OtherHolder>& other) {
        m_container_ptr = other.m_container_ptr;
        m_storage       = other.m_storage;
        m_it            = other.m_it;
        // 如果 other 拥有值，需要更新指针
        if (!m_storage.empty()) {
            m_container_ptr = &m_storage.template get<std::remove_reference_t<OtherHolder>>();
        }
        return *this;
    }

    // 需要友元声明以访问私有成员
    template <typename C, typename H>
    friend class iterator_wrapper;

    /**
     * @brief Python __next__() 方法的实现
     *
     * 检查迭代器是否到达末尾，如果到达则抛出 StopIteration，否则返回当前值并递增
     *
     * @return 当前迭代器指向的值
     * @throw mcpy::stop_iteration 如果迭代器到达末尾
     */
    template <typename T>
    T __next__() const {
        MC_ASSERT_THROW(m_container_ptr != nullptr, mc::runtime_exception, "迭代器未初始化");
        if (!m_it.has_value()) {
            m_it = m_container_ptr->begin();
        }
        auto m_end = m_container_ptr->end();
        MC_ASSERT_THROW(*m_it != m_end, mcpy::stop_iteration, "迭代器到达末尾");
        value_type result = **m_it;
        ++(*m_it);
        return mcpy::cast<T>(result);
    }

    /**
     * @brief Python __next__(default) 方法的实现 - 支持默认值
     *
     * 检查迭代器是否到达末尾，如果到达则返回默认值，否则返回当前值并递增
     * 返回 std::optional<T>
     *
     * @tparam T 目标类型
     * @tparam Default 默认值类型（value_type 或 nullptr_t）
     * @param default_value 默认值
     * @return std::optional<T>
     */
    template <typename T, typename Default>
    std::optional<T> __next__(Default&& default_value) const {
        MC_ASSERT_THROW(m_container_ptr != nullptr, mc::runtime_exception, "迭代器未初始化");
        if (!m_it.has_value()) {
            m_it = m_container_ptr->begin();
        }
        auto m_end = m_container_ptr->end();

        if (*m_it == m_end) {
            return std::nullopt;
        }
        value_type result = **m_it;
        ++(*m_it);
        return std::optional<T>(mcpy::cast<T>(result));
    }
};

/**
 * @brief 字典迭代器包装类（返回键）
 *
 * 特殊处理字典，因为返回的是键而不是 entry
 *
 * @tparam Holder 存储策略
 */
template <typename Container, typename Holder>
class dict_iterator_wrapper {
private:
    Holder                                     m_holder;
    mutable typename Container::const_iterator m_it;
    mutable bool                               m_initialized;
    mutable bool                               m_valid; // 标记是否已初始化容器

public:
    using key_type = typename Container::key_type;

    dict_iterator_wrapper() : m_initialized(false), m_valid(false) {
    }

    explicit dict_iterator_wrapper(Holder dict)
        : m_holder(std::forward<Holder>(dict)), m_initialized(false), m_valid(true) {
    }

    // 拷贝构造函数
    dict_iterator_wrapper(const dict_iterator_wrapper& other)
        : m_holder(other.m_holder), m_it(other.m_it), m_initialized(other.m_initialized), m_valid(other.m_valid) {
    }

    // 移动构造函数
    dict_iterator_wrapper(dict_iterator_wrapper&& other) noexcept
        : m_holder(std::move(other.m_holder)), m_it(std::move(other.m_it)), m_initialized(other.m_initialized), m_valid(other.m_valid) {
    }

    // 赋值操作符（用于异步函数中的赋值）
    dict_iterator_wrapper& operator=(dict_iterator_wrapper&& other) noexcept {
        if (this != &other) {
            m_holder      = std::move(other.m_holder);
            m_it          = std::move(other.m_it);
            m_initialized = other.m_initialized;
            m_valid       = other.m_valid;
        }
        return *this;
    }

    dict_iterator_wrapper& operator=(const dict_iterator_wrapper& other) {
        if (this != &other) {
            m_holder      = other.m_holder;
            m_it          = other.m_it;
            m_initialized = other.m_initialized;
            m_valid       = other.m_valid;
        }
        return *this;
    }

    // 模板化赋值操作符（允许不同的 Holder 类型）
    template <typename OtherHolder>
    dict_iterator_wrapper& operator=(dict_iterator_wrapper<Container, OtherHolder>&& other) {
        m_holder      = std::forward<OtherHolder>(other.m_holder);
        m_it          = std::move(other.m_it);
        m_initialized = other.m_initialized;
        m_valid       = other.m_valid;
        return *this;
    }

    template <typename OtherHolder>
    dict_iterator_wrapper& operator=(const dict_iterator_wrapper<Container, OtherHolder>& other) {
        m_holder      = other.m_holder;
        m_it          = other.m_it;
        m_initialized = other.m_initialized;
        m_valid       = other.m_valid;
        return *this;
    }

    // 需要友元声明以访问私有成员
    template <typename C, typename H>
    friend class dict_iterator_wrapper;

    /**
     * @brief Python __next__() 方法的实现 - 字典版本（返回键）
     *
     * 检查迭代器是否到达末尾，如果到达则抛出 StopIteration，否则返回当前键并递增
     *
     * @return 当前迭代器指向的键
     * @throw mcpy::stop_iteration 如果迭代器到达末尾
     */
    template <typename T>
    T __next__() const {
        MC_ASSERT_THROW(m_valid, mc::runtime_exception, "迭代器未初始化");
        const auto& dict = get_dict();
        if (!m_initialized) {
            m_it          = dict.begin();
            m_initialized = true;
        }
        auto m_end = dict.end();
        MC_ASSERT_THROW(m_it != m_end, mcpy::stop_iteration, "迭代器到达末尾");
        auto result = m_it->key;
        ++m_it;
        return mcpy::cast<T>(result);
    }

    /**
     * @brief Python __next__(default) 方法的实现 - 字典版本（返回键）
     *
     * 检查迭代器是否到达末尾，如果到达则返回默认值，否则返回当前键并递增
     * 返回 std::optional<T>
     *
     * @tparam Default 默认值类型（key_type 或 nullptr_t）
     * @param default_value 默认值
     * @return std::optional<T>
     */
    template <typename T, typename Default>
    std::optional<T> __next__(Default&& default_value) const {
        MC_ASSERT_THROW(m_valid, mc::runtime_exception, "迭代器未初始化");
        const auto& dict = get_dict();
        if (!m_initialized) {
            m_it          = dict.begin();
            m_initialized = true;
        }
        auto m_end = dict.end();

        if (m_it == m_end) {
            if constexpr (std::is_same_v<std::decay_t<Default>, std::nullptr_t>) {
                return std::nullopt;
            } else {
                return std::optional<T>(std::forward<Default>(default_value));
            }
        }
        auto result = m_it->key;
        ++m_it;
        return std::optional<T>(mcpy::cast<T>(result));
    }

private:
    const Container& get_dict() const {
        if constexpr (std::is_reference_v<Holder>) {
            return m_holder;
        } else {
            return m_holder;
        }
    }
};

} // namespace detail

/**
 * @brief Python iter() 函数的通用包装
 *
 * Python: iter(container) -> iterator_wrapper
 * C++:    mcpy::iter_wrapper(container) -> iterator_wrapper
 *
 * 使用完美转发 + 存储策略自动推导：
 * - 左值容器 → 存储 const Container&（零拷贝）
 * - 右值容器 → 存储 Container（移动语义，拥有数据）
 *
 * 示例：
 *   mc::array<int> v = {1, 2, 3};
 *   iter_wrapper(v)        // 存储 const mc::array<int>&
 *   iter_wrapper({1,2,3})  // 存储 mc::array<int>（临时对象）
 *
 * @tparam Container 容器类型
 * @param container 容器（左值或右值）
 * @return iterator_wrapper 对象
 */
template <typename Container>
inline auto iter_wrapper(Container&& container) {
    using ContainerType = std::remove_cv_t<std::remove_reference_t<Container>>;
    using StorageType   = detail::storage_type_t<Container&&>;

    if constexpr (detail::is_key_value_container<ContainerType>::value) {
        return detail::dict_iterator_wrapper<ContainerType, StorageType>(std::forward<Container>(container));
    } else {
        return detail::iterator_wrapper<ContainerType, StorageType>(
            std::forward<Container>(container));
    }
}

} // namespace mcpy

#endif // MC_BUILTINS_GLOBAL_FUNCTIONS_H
